
#ifndef __CE_NODE_H__
#define __CE_NODE_H__

#include <cecore/iqf.h>
#include <cegfx/ce.h>
#include <cegfx/ceboundingbox.h>
#include <cegfx/ceexport.h>
#include <cegfx/cerange.h>
#include <cegfx/cetransform.h>
#include <cegfx/ceupdateenv.h>
#include <vector>

struct iNodeAnimator;
class CE_GFX_API ceNode : public virtual iBase
{
	IQF_DECLARATION;
public:
	enum NodeType
	{
		NT_Collection,
		NT_GeometryNode,
		NT_LightNode,
	};

private:
	ceTransform	transform;

	iNodeAnimator*	animator;

	NodeType				type;

	ceBoundingBox		bbox;

	CullingMode			cullingMode;

	ceRange					range;

protected:
	ceNode (NodeType type);
	~ceNode ();

	virtual void UpdateBoundingBox (D3DXMATRIX* matrix, ceBoundingBox* bbox);

public:
	/**
	 * \name Transformation
	 * @{
	 */
	/**
	 * \brief Begins the transformation.
	 * 
	 * This method must be called prior to every changed within the 
	 * transform object.
	 */
	virtual void BeginTransformation ();
	/**
	 * \brief Ends the transformation.
	 * 
	 * This method must be called after the transformation is done.
	 * Calling this method without a prior call to BeginTransformation()
	 * is undefined.
	 */
	virtual void EndTransformation ();

	/**
	 * \brief Reset the transformation
	 * \param transform The new transformation
	 */
	void SetTransform (const ceTransform& transform);
	/**
	 * \brief Returns the current transform.
	 * \return The current transform.
	 */
	ceTransform& GetTransform ();
	/**
	 * \brief Returns the current transform.
	 * \return The current transform.
	 */
	const ceTransform& GetTransform () const;
	/**
	 * @}
	 */
	void SetNodeAnimator (iNodeAnimator* animator);
	iNodeAnimator* GetNodeAnimator ();
	const iNodeAnimator* GetNodeAnimator () const;

	ceBoundingBox& GetBoundingBox ();
	const ceBoundingBox& GetBoundingBox () const;

	virtual void Update (const ceUpdateEnv& env);

	NodeType GetNodeType () const;

	void SetCullingMode (CullingMode mode);
	CullingMode GetCullingMode () const;

	void SetRenderingRange (float max);
	void SetRenderingRange (float min, float max);
	const ceRange& GetRenderingRange () const;

};

typedef ceNode *ceNodePtr;
typedef std::vector<ceNodePtr> ceNodeVector;

#endif /* ! __CE_NODE_H__ */ 
